\section{内存模型和名称空间}
现代C++程序中通常将程序分成:
\begin{itemize}
    \item 头文件：包含结构声明和使用这些结构的函数原型。
    \item 源代码文件：包含与结构相关的函数代码。
    \item 源代码文件：包含调用与结构相关的函数的代码
\end{itemize}
头文件中常常包含的内容:
\begin{itemize}
    \item 函数原型
    \item 使用\#define或者const定义的符号常量。
    \item 结构声明
    \item 类声明
    \item 模板声明
    \item 内联函数
\end{itemize}

链接性

可以使用外部变量在多个文件程序的不同部分之间共享数据：可以使用链接性为内部的静态变量在同一个文件中的多个函数之间共享数据(名称空间提供了另一种共享数据的方法)。另外，如果将作用于为整个文件的变量变为静态，就不必担心其名称和其他文件中的作用域为整个文件的变量发生冲突。

在twofile1.cc文件中tom，dick为外部变量harry为静态外部变量，在twofile2.cc文件中remote\_access使用extern和第一个文件共享tom。接下来该文件定义一个名为dick的静态变量。\textcolor{red}{static限定符使得该变量被限制在这个文件内，并覆盖相应的全局定义。}其内部定义的变量harry不会和第一个文件中的harry冲突，因为后者的链接性为内部的。
\cppfile{code/namespace/twofile1.cc}
外部程序代码:
\cppfile{code/namespace/twofile2.cc}
\textbf{作用域}：名称在文件（翻译单元）的多大范围内可见。例如函数中定义的变量只能在该函数中使用而不能在其他函数中可用，在文件中函数之前定义的变量能被所有函数使用。

\textbf{链接性}：表述了名称如何在不同的单元间共享。链接性为\textcolor{red}{外部}的名称可以在文件间共享，链接性为内部的名称只能由一个文件中的函数共享。

静态变量的作用域是全局还是局部取决于它是如何被定义的，在函数原型作用域中使用的名称只在包含参数列表的括号内可用。

\subsection{静态持续变量}
C++为静态存储持续变量提供了三种链接性：外部链接性（可以再其他文件中访问），内部链接性（只能在当前文件中访问）和无连接性（只能在当前函数或代码块中访问）。由于静态变量在整个函数执行期间是一直存在的，因此程序不需要使用特殊的装置处理它。编译器将分配固定的内存块存储所有的静态变量，这些变量在整个程序执行期间一直存在。另外，如果没有显式的初始化静态变量，编译器将把它设置为0。在默认情况下，静态数组和结构将每个元素或成员的所有位都设置为0.

要创建链接性为外部连的静态持续变量，必须在代码块中声明它；要创建链接性为内部的静态持续变量，必须在代码块的外面声明它，并使用static限定符，要创建没有链接性的静态持续变量，必须在代码块内声明它，并使用static限定符。

零初始化和常量表达式被统称为静态初始化，这意味着在编译器处理文件（翻译单元）时初始化变量。动态初始化意味着变量将在编译后初始化。首先，所有的静态变量都被零初始化，而不管程序员是否显式的初始化了它/接下来，如果使用常量表达式初始化了变量，且编译器根据文件内容(包括被包含的头文件)就可以计算表达式了，编译器将执行常量表达式初始化。

单定义规则：一方面在内个使用外部变量的文件中，都必须声明它；另一方面C++有单定义规则，该规则指出，变量只能有一次定义。为了满足这种需求，C++提供了两种变量声明。一种是定义声明或简称为\textcolor{red}{定义},他给变量分配存储空间；另一种是引用声明或简称\textcolor{red}{声明}，它不给变量分配存储空间，因为它引用已有的变量。引用声明使用关键字\textcolor{red}{extern}，且不进行初始化；否则声明为定义，导致分配存储空间。
\cppfile{code/namespace/ns2/external.cc}
\cppfile{code/namespace/ns2/extern.cc}
作用域解析运算符\textcolor{red}{::}放在变量的前面的时候该运算符表示使用变量的全局版本。
\subsection{说明符和限定符}
\textbf{mutable}\\
使用它指出，即使结构体或者类被声明为const，其中某个成员也可以被修改。如下：
\begin{cpp}
    struct data
        {
            char name[30];
            mutable int accesses;
        }
    const data veep = {"bleedingfight",10};
    strcpy(veep.name,"talor")//不允许
    veep.accesses++;//允许
\end{cpp}
在C++中，const限定符对默认存储类型稍有影响。在默认情况下，全局变量的链接性为外部的，但是const全局变量的链接性为内部的。也就是说，在C++看来，全局定义就像使用了static说明符一样。
\begin{cpp}
    const int fingers = 10;//链接性为内部
    int main(void)
    {
        }
\end{cpp}
C++修改了常量类型的规则，加入将一组常亮放在头文件中，并在同一个程序的多个文件中使用该头文件。那么预处理器将头文件的内容包含到每个原文件中后，所有的源文件都含有类似的定义：
\begin{cpp}
    const int fingers = 10;
    const char * warning = "Wak";
\end{cpp}
如果全局const声明的链接性像常规变量那样是外部的，则根据单定义规则，这将出错。也就是说，只能有一个文件可以包含前面的声明，而其它的文件必须使用extern关键字来提供声明。另外只有没有使用extern关键字的声明才能进行初始化：
\begin{cpp}
    // 如果常量有外部链接性将需要extern
    extern const int fingers;
    extern const char * warning;
\end{cpp}
如果希望某个常量是外部链接性可以使用\cppinline{extern const int states = 50;}
在这种情况下必须在所有使用该常量的文件中使用extern声明它。这和常规外部变量不同，定义常规外部变量时，不必使用extern关键字，但是在使用该变量的其他文件中必须使用extern，然而，鉴于单个const在多个文件之间共享，因此只有一个文件可以对它初始化。

函数的链接性默认是外部的，如果想定义链接性为内部必须使用static。这意味着声明的函数只能在函数所在文件中可见，还意味着可以再其他文件中定义同名函数。和变量一样，在定义静态函数的文件中，静态函数将覆盖外部定义，\textcolor{red}{但使用该函数的每个文件都应该包含其函数原型}。

